package com.example.casserver.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class LogoutNotificationService {

    private static final Logger logger = LoggerFactory.getLogger(LogoutNotificationService.class);
    private static final int MAX_RETRY_ATTEMPTS = 3;
    private static final long RETRY_DELAY_MS = 1000; // 1秒

    private final RestTemplate restTemplate;

    // 使用用户名作为key，存储该用户所有的服务票据信息
    private final Map<String, Map<String, String>> userServiceMap = new ConcurrentHashMap<>();

    public LogoutNotificationService() {
        this.restTemplate = new RestTemplate();
    }

    /**
     * 注册服务URL
     *
     * @param username   用户名
     * @param ticket     服务票据
     * @param serviceUrl 服务URL
     */
    public void registerService(String username, String ticket, String serviceUrl) {
        userServiceMap.computeIfAbsent(username, k -> new ConcurrentHashMap<>())
                .put(ticket, serviceUrl);
        logger.info("Registered service URL for user: {}, ticket: {}", username, ticket);
    }

    /**
     * 发送登出通知
     *
     * @param username 用户名
     */
    @Async
    public void notifyLogout(String username) {
        Map<String, String> userServices = userServiceMap.remove(username);
        if (userServices == null || userServices.isEmpty()) {
            logger.info("No services to notify for user: {}", username);
            return;
        }

        logger.info("Starting logout notification for user: {} to {} services",
                username, userServices.size());

        for (Map.Entry<String, String> entry : userServices.entrySet()) {
            String ticket = entry.getKey();
            String serviceUrl = entry.getValue();
            notifyService(username, ticket, serviceUrl);
        }
    }

    /**
     * 通知单个服务
     */
    private void notifyService(String username, String ticket, String serviceUrl) {
        String logoutUrl = UriComponentsBuilder.fromUriString(serviceUrl)
                .path("/logout")
                .queryParam("ticket", ticket)
                .build()
                .toUriString();

        for (int attempt = 1; attempt <= MAX_RETRY_ATTEMPTS; attempt++) {
            try {
                logger.debug("Attempting to notify service: {} (attempt {}/{})",
                        serviceUrl, attempt, MAX_RETRY_ATTEMPTS);

                ResponseEntity<String> response = restTemplate.getForEntity(logoutUrl, String.class);

                if (response.getStatusCode().is2xxSuccessful()) {
                    logger.info("Successfully notified service: {} for user: {}", serviceUrl, username);
                    return;
                }

                logger.warn("Service notification failed with status: {}", response.getStatusCode());

            } catch (Exception e) {
                logger.error("Error notifying service: {} (attempt {}/{}): {}",
                        serviceUrl, attempt, MAX_RETRY_ATTEMPTS, e.getMessage());

                if (attempt < MAX_RETRY_ATTEMPTS) {
                    try {
                        Thread.sleep(RETRY_DELAY_MS * attempt);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        return;
                    }
                }
            }
        }

        logger.error("Failed to notify service after {} attempts: {}", MAX_RETRY_ATTEMPTS, serviceUrl);
    }

    /**
     * 移除服务注册
     *
     * @param username 用户名
     * @param ticket   服务票据
     */
    public void removeService(String username, String ticket) {
        Map<String, String> userServices = userServiceMap.get(username);
        if (userServices != null) {
            userServices.remove(ticket);
            if (userServices.isEmpty()) {
                userServiceMap.remove(username);
            }
            logger.info("Removed service registration for user: {}, ticket: {}", username, ticket);
        }
    }

    /**
     * 获取用户的所有已注册服务
     *
     * @param username 用户名
     * @return 服务URL集合
     */
    public Set<String> getRegisteredServices(String username) {
        Map<String, String> userServices = userServiceMap.get(username);
        return userServices != null ? Set.copyOf(userServices.values()) : Set.of();
    }
} 